<?php

namespace app\zyhsapi\lib;

use app\common\lib\astrolog\Astrolog;
use app\common\model\AstroSettingUser1751;
use app\common\model\DivinationSabienTips;
use app\common\model\DivinationTips;

class ZyhsDivinationLib
{
    /**
     * 获取骰子 经典模式 信息
     * @param array $detail 骰子信息
     * @return array
     */
    public function getDiceInfo(array $detail)
    {
        // 计算骰子六种模式
        $dice_status = $this->diceStatus($detail['planet'], $detail['sign'], $detail['house'], $detail['deg']);

        $result = [
            'did' => $detail['id'],
            'question' => $detail['question'],
            'planet' => $detail['planet'],
            'house' => $detail['house'],
            'sign' => $detail['sign'],
            'love_status' => $dice_status['love'],
            'health_status' => $dice_status['health'],
            'trip_status' => $dice_status['trip'],
            'money_status' => $dice_status['money'],
            'career_status' => $dice_status['career'],
            'study_status' => $dice_status['study'],
            'time' => $detail['create_time'],
        ];

        //根据提问详情获取骰子词条
        $DivinationTips = new DivinationTips();
        $result['planet_text'] = $DivinationTips->getDetail('p-' . $detail['planet']);
        $result['sign_text'] = $DivinationTips->getDetail('s-' . $detail['sign']);
        $result['house_text'] = $DivinationTips->getDetail('h-' . $detail['house']);

        return $result;
    }

    /**
     * 骰子吉凶
     * @param int $planet 行星id
     * @param int $sign 星座id
     * @param int $house 宫位id
     * @param float $deg 落星座度数
     * @return array
     */
    private function diceStatus($planet = null, $sign = null, $house = null, $deg = null)
    {
        // 初始化
        $score = [
            'love' => 0,
            'marital' => 0,
            'health' => 0,
            'trip' => 0,
            'money' => 0,
            'career' => 0,
            'study' => 0,
        ];
        // 计算行星得分
        switch ($planet)
        {
            case 0:
                $score['love'] += 4;
                $score['marital'] += 9;
                $score['health'] += 10;
                $score['trip'] += 10;
                $score['money'] += 2;
                $score['career'] += 10;
                $score['study'] += 10;
                break;
            case 1:
                $score['love'] += 5;
                $score['marital'] += 10;
                $score['health'] += -2;
                $score['trip'] += 1;
                $score['money'] += 8;
                $score['career'] += 3;
                $score['study'] += 1;
                break;
            case 2:
                $score['love'] += 2;
                $score['marital'] += 2;
                $score['health'] += 2;
                $score['trip'] += 9;
                $score['money'] += 1;
                $score['career'] += 2;
                $score['study'] += 9;
                break;
            case 3:
                $score['love'] += 10;
                $score['marital'] += 8;
                $score['health'] += 9;
                $score['trip'] += 9;
                $score['money'] += 10;
                $score['career'] += 4;
                $score['study'] += 9;
                break;
            case 4:
                $score['love'] += -5;
                $score['marital'] += -3;
                $score['health'] += -6;
                $score['trip'] += -8;
                $score['money'] += -5;
                $score['career'] += -3;
                $score['study'] += -8;
                break;
            case 5:
                $score['love'] += 8;
                $score['marital'] += 4;
                $score['health'] += 8;
                $score['trip'] += 10;
                $score['money'] += 9;
                $score['career'] += 10;
                $score['study'] += 10;
                break;
            case 6:
                $score['love'] += -10;
                $score['marital'] += 1;
                $score['health'] += -7;
                $score['trip'] += -3;
                $score['money'] += -7;
                $score['career'] += -4;
                $score['study'] += -3;
                break;
            case 7:
                $score['love'] += -10;
                $score['marital'] += -10;
                $score['health'] += -2;
                $score['trip'] += 5;
                $score['money'] += 5;
                $score['career'] += 1;
                $score['study'] += 5;
                break;
            case 8:
                $score['love'] += -8;
                $score['marital'] += -10;
                $score['health'] += -4;
                $score['trip'] += -2;
                $score['money'] += -6;
                $score['career'] += -10;
                $score['study'] += -2;
                break;
            case 9:
                $score['love'] += -6;
                $score['marital'] += -6;
                $score['health'] += -10;
                $score['trip'] += -4;
                $score['money'] += 6;
                $score['career'] += -7;
                $score['study'] += -4;
                break;
            case 12:
                $score['love'] += 9;
                $score['marital'] += 9;
                $score['health'] += 9;
                $score['trip'] += 9;
                $score['money'] += 9;
                $score['career'] += 9;
                $score['study'] += 9;
                break;
            case 16:
                $score['love'] -= 9;
                $score['marital'] -= 9;
                $score['health'] -= 9;
                $score['trip'] -= 9;
                $score['money'] -= 9;
                $score['career'] -= 9;
                $score['study'] -= 9;
                break;
        }
        // 庙+5，旺+4，三分+2，界+1，面+0.5，浮游时吉星【金木】+1.5，凶星【火土】-1.5，陷落-4
        $sign_score = 0;
        $is_change = false;
        if ($planet <= 9)
        {
            $ancient = config('astrolog.ancient')[$sign];// 古典数据

            if ($ancient[0] == $planet)
            {
                $sign_score += 5;// 入庙 +5
                $is_change = true;
            }
            if ($ancient[1] == $planet)
            {
                $sign_score += 4;// 擢升 旺 +4
                $is_change = true;
            }
            if (in_array($planet, $ancient[2]))
            {
                $sign_score += 2;// 三分 +2
                $is_change = true;
            }
            for ($i = 0; $i < 6; $i++)
            {
                if (
                    $planet &&
                    ($deg >= $ancient[3]['default'][1][$i]
                        && $deg < $ancient[3]['default'][1][$i + 1])
                )
                {
                    $sign_score += 2;// 界 +1
                    $is_change = true;
                }
            }
            if ($ancient[4][floor($deg / 10)] == $planet)
            {
                $sign_score += 0.5;// 面 +0.5
                $is_change = true;
            }
            $fall = ($sign <= 6) ? ($sign + 6) : ($sign - 6);
            $fall_ancient = config('astrolog.ancient')[$fall];
            if ($fall_ancient[0] == $planet)
            {
                $sign_score -= 5;// 失势 -4
                $is_change = true;
            }
            if ($fall_ancient[1] == $planet)
            {
                $sign_score -= 4;// 落陷 -4
                $is_change = true;
            }
            // 天王星  入庙 失势
            if ($planet == 7)
            {
                if ($sign == 11)
                {
                    $sign_score += 5;
                    $is_change = true;
                } elseif ($sign == 5)
                {
                    $sign_score -= 5;
                    $is_change = true;
                }
            }
            // 海王星  入庙 失势
            if ($planet == 8)
            {
                if ($sign == 12)
                {
                    $sign_score += 5;
                    $is_change = true;
                } elseif ($sign == 6)
                {
                    $sign_score -= 5;
                    $is_change = true;
                }
            }
            // 冥王星  入庙 失势
            if ($planet == 9)
            {
                if ($sign == 8)
                {
                    $sign_score += 5;
                    $is_change = true;
                } elseif ($sign == 2)
                {
                    $sign_score -= 5;
                    $is_change = true;
                }
            }
        }
        // 游走状态
        if ($is_change === false)
        {
            if ($planet == 3 || $planet == 5) $sign_score += 1.5;
            elseif ($planet == 4 || $planet == 6) $sign_score -= 1.5;
        }

        $score['love'] += $sign_score;
        $score['marital'] += $sign_score;
        $score['health'] += $sign_score;
        $score['trip'] += $sign_score;
        $score['money'] += $sign_score;
        $score['career'] += $sign_score;
        $score['study'] += $sign_score;

        switch ($house)
        {
            case 1:
                $score['love'] *= 1.5;
                $score['marital'] *= 1.5;
                $score['health'] *= 2;
                $score['trip'] *= 1.5;
                $score['money'] *= 1.5;
                $score['career'] *= 1.5;
                $score['study'] *= 1.5;
                break;
            case 2:
                $score['love'] *= 1;
                $score['marital'] *= 1;
                $score['health'] *= 1;
                $score['trip'] *= 1;
                $score['money'] *= 2;
                $score['career'] *= 1;
                $score['study'] *= 1;
                break;
            case 3:
                $score['love'] *= 1;
                $score['marital'] *= 1;
                $score['health'] *= 1;
                $score['trip'] *= 2;
                $score['money'] *= 1;
                $score['career'] *= 1;
                $score['study'] *= 2;
                break;
            case 4:
                $score['love'] *= 1.1;
                $score['marital'] *= 1.2;
                $score['health'] *= 1;
                $score['trip'] *= 1;
                $score['money'] *= 1.2;
                $score['career'] *= 1;
                $score['study'] *= 1;
                break;
            case 5:
                $score['love'] *= 2;
                $score['marital'] *= 1.1;
                $score['health'] += 5;
                $score['trip'] *= 1;
                $score['money'] *= 1.5;
                $score['career'] *= 1;
                $score['study'] *= 1;
                break;
            case 6:
                $score['love'] -= 15;
                $score['marital'] -= 15;
                $score['health'] *= 2;
                $score['trip'] -= 12;
                $score['money'] -= 10;
                $score['career'] *= 1.3;
                $score['study'] *= 1.3;
                break;
            case 7:
                $score['love'] *= 2;
                $score['marital'] *= 2;
                $score['health'] *= 1;
                $score['trip'] *= 1.5;
                $score['money'] *= 1;
                $score['career'] *= 1.2;
                $score['study'] *= 1;
                break;
            case 8:
                $score['love'] -= 15;
                $score['marital'] -= 15;
                $score['health'] -= 20;
                $score['trip'] -= 15;
                $score['money'] *= 1.5;
                $score['career'] -= 10;
                $score['study'] -= 10;
                break;
            case 9:
                $score['love'] *= 1;
                $score['marital'] *= 1;
                $score['health'] += 5;
                $score['trip'] *= 2;
                $score['money'] *= 1;
                $score['career'] *= 1.1;
                $score['study'] *= 2;
                break;
            case 10:
                $score['love'] *= 1;
                $score['marital'] *= 1;
                $score['health'] += 5;
                $score['trip'] *= 1;
                $score['money'] *= 1.2;
                $score['career'] *= 2;
                $score['study'] += 5;
                break;
            case 11:
                $score['love'] *= 1.1;
                $score['marital'] *= 1;
                $score['health'] *= 1;
                $score['trip'] *= 1.2;
                $score['money'] *= 1.3;
                $score['career'] *= 1.5;
                $score['study'] += 5;
                break;
            case 12:
                $score['love'] -= 20;
                $score['marital'] -= 20;
                $score['health'] -= 20;
                $score['trip'] -= 20;
                $score['money'] -= 20;
                $score['career'] -= 20;
                $score['study'] -= 20;
                break;
        }

        $result = [];
        foreach ($score as $k => $s)
        {
            if ($s < -25) $result[$k] = '凶';// 低于-25	凶
            elseif ($s >= -25 && $s < -15) $result[$k] = '不利';// 低于-15	不利
            elseif ($s >= -15 && $s < -5) $result[$k] = '不顺';// 低于-5	不顺
            elseif ($s >= -5 && $s < 5) $result[$k] = '平';// 低于5	平
            elseif ($s >= 5 && $s < 15) $result[$k] = '小吉';// 高于5	小吉
            elseif ($s >= 15 && $s < 25) $result[$k] = '吉';// 高于15	吉
            elseif ($s >= 25) $result[$k] = '大吉';// 高于25	大吉
        }
        return $result;
    }

    /**
     * 获取骰子 专业模式 信息
     * @param array $detail
     * @return array
     */
    public function specialtyInfo(array $detail)
    {
        $divination_deg = ($detail['sign'] - 1) * 30 + $detail['deg'];// 骰子度数
        $sabien_text = (new DivinationSabienTips())->getDetail(['sign' => $detail['sign'], 'deg' => floor($detail['deg'])]);

        $details = [
            'did' => $detail['id'],
            'divination' => [
                'id' => $detail['planet'],
                'deg' => $divination_deg,
                'in_sign_id' => $detail['sign'],
                'in_sign_deg' => in_sign_deg($divination_deg),
                'in_sign_deg_e' => floatval($detail['deg']),
                'in_house_id' => $detail['house'],
                'ancient' => $this->get_ancient_status($detail['planet'], $detail['sign'], floatval($detail['deg'])),
                'sabien' => $sabien_text['text'],

            ],
        ];
        // 12宫宫头度数【整宫制】
        $asc_sign = (int)(ceil($divination_deg / 30) + 12 - $detail['house'] * 1);
        if ($asc_sign > 12) $asc_sign -= 12;
        elseif ($asc_sign < 0) $asc_sign += 12;
        $asc = $asc_sign * 30;
        for ($i = 0; $i <= 11; $i++)
        {
            $deg = $asc + 30 * $i;
            if ($deg >= 360) $deg = $deg - 360;
            $details['house'][$i + 1] = [
                'deg' => $deg,
                'in_sign_id' => $deg / 30 + 1,
                'in_sign_deg' => 0,
            ];
        }
        // 格林尼治时间
        $truetime = get_base_time($detail['create_time'], floor($detail['timezone']));

        $utdatenow = strftime("%d.%m.%Y", $truetime);
        $utnow = strftime("%H:%M:%S", $truetime);

        $asps_display = [0, 60, 90, 120, 180];
        $asp_orb = [0 => 2, 60 => 1, 90 => 2, 120 => 2, 180 => 2];// 2 1 2 2 2

        // 求出当前天象的日月水金火木土天海冥的黄经度数
        $exec_str = config('astrolog.prefix') . " -b{$utdatenow} -ut{$utnow} -p0123456789 -eswe -fl -head";

        exec($exec_str, $out);

        $now_planet = [];

        foreach ($out as $o) $now_planet[] = $o * 1;
        // 检测是否成相
        $details['planets'] = null;
        $details['divination']['phase'] = null;
        foreach ($now_planet as $k => $p2)
        {
            $da = abs($p2 - $divination_deg);
            if ($da > 180) $da = 360 - $da;
            foreach ($asps_display as $asp)
            {
                $asp_orb_deg = abs($da - $asp);
                $or_orb = $asp_orb[$asp];
                if ($asp_orb_deg <= $or_orb)
                {
                    $phase = [
                        'id1' => $detail['planet'],
                        'id2' => $k,
                        'phase_e' => $asp,
                        'phase_orb' => $asp_orb_deg,
                        'phase_or_orb' => $or_orb,
                    ];
                    $details['divination']['phase'][] = $phase;
                    // 记录天象行星信息
                    $p2_in_sign_id = ceil($p2 / 30);
                    $p2_in_sign_id_e = $p2 - ($p2_in_sign_id - 1) * 30;
                    $p2_in_house_id = null;
                    foreach ($details['house'] as $h => $dh)
                    {
                        if ($p2 >= $dh['deg'] && $p2 < $dh['in_sign_id'] * 30) $p2_in_house_id = $h;
                    }
                    $details['planets'][] = [
                        'id' => $k,
                        'deg' => $p2,
                        'in_sign_id' => $p2_in_sign_id,
                        'in_sign_deg' => in_sign_deg($p2),
                        'in_sign_deg_e' => $p2_in_sign_id_e,
                        'in_house_id' => $p2_in_house_id,
                        'ancient' => $this->get_ancient_status($k, $p2_in_sign_id, $p2_in_sign_id_e),
                        'phase' => [$phase],
                    ];
                }
            }
        }

        return $details;
    }

    /**
     * 获取行星古典七段势力状态
     * @param null $planet
     * @param null $sign
     * @param float $deg
     * @return array|null
     */
    private function get_ancient_status($planet = null, $sign = null, $deg = 0.0)
    {
        // 非古典七星落座位置也有该位置庙旺弱陷界十度信息
        if ($planet === null || $planet < 0 || $sign === null) return null;
        $ret = [
            'power' => 0,
            'walls' => -1, 'walls_cn' => '',// 庙
            'promote' => -1, 'promote_cn' => '',// 旺
            'trisection' => -1, 'trisection_cn' => '',// 三分
            'extent' => -1, 'extent_cn' => '',// 界
            'period' => -1, 'period_cn' => '',// 面
            'migration' => -1, 'migration_cn' => '',// 游走
            'or_extent_planet_id' => -1, 'or_period_planet_id' => -1,
        ];

        $fall = ($sign <= 6) ? ($sign + 6) : ($sign - 6);

        $config_ancient = config('astrolog.ancient')[$sign];
        $config_ancient_fall = config('astrolog.ancient')[$fall];

        // 入庙
        if ($planet < 7 && $config_ancient[0] == $planet)
        {
            $ret['power'] += 5;
            $ret['walls'] = 1;
            $ret['walls_cn'] = '入庙';
        } elseif ($planet < 7 && $config_ancient_fall[0] == $planet)
        {
            $ret['power'] -= 5;
            $ret['walls'] = 2;
            $ret['walls_cn'] = '失势';
        }

        // 天王星  入庙 失势
        if ($planet == 7)
        {
            if ($sign == 11)
            {
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($sign == 5)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 海王星  入庙 失势
        if ($planet == 8)
        {
            if ($sign == 12)
            {
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($sign == 6)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 冥王星  入庙 失势
        if ($planet == 9)
        {
            if ($sign == 8)
            {
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($sign == 2)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 擢升
        if ($config_ancient[1] !== '' && $config_ancient[1] == $planet)
        {
            $ret['power'] += 4;
            $ret['promote'] = 1;
            $ret['promote_cn'] = '擢升';
        } elseif ($config_ancient_fall[1] !== '' && $config_ancient_fall[1] == $planet)
        {
            $ret['power'] -= 4;
            $ret['promote'] = 2;
            $ret['promote_cn'] = '落陷';
        }
        // 三分
        if (in_array($planet, $config_ancient[2]))
        {
            $ret['power'] += 3;
            $ret['trisection'] = 1;
            $ret['trisection_cn'] = '三分';
        }
        // 界主 界主为1 +2
//        if (session('xzns.extent') == 'ptolemy_world')
//            $extent = $config_ancient[3]['ptolemy_world'];
//        else
        // 使用埃及界
        $extent = $config_ancient[3]['default'];

        for ($i = 0; $i < 5; $i++)
        {
            if ($deg > $extent[1][$i] && $deg < $extent[1][$i + 1])
            {
                if ($extent[0][$i] == $planet)
                {
                    $ret['power'] += 2;
                    $ret['extent'] = 1;
                    $ret['extent_cn'] = '界主';
                }
                $ret['or_extent_planet_id'] = $extent[0][$i];
            }
        }
        // 旬主或十度
        for ($i = 0; $i < 3; $i++)
        {
            $min = $i * 10;
            $max = $min + 10;
            if ($deg > $min && $deg < $max)
            {
                if ($config_ancient[4][$i] == $planet)
                {
                    $ret['power'] += 1;
                    $ret['period'] = 1;
                    $ret['period_cn'] = '旬主';
                }
                $ret['or_period_planet_id'] = $config_ancient[4][$i];
            }
        }

        if ($ret['walls'] == -1 && $ret['promote'] == -1 && $ret['trisection'] == -1 && $ret['extent'] == -1 && $ret['period'] == -1 && $ret['power'] == 0 && $planet < 7)
        {
            $ret['power'] = -5;
            $ret['migration'] = 1;
            $ret['migration_cn'] = '游走';
        }
        if ($planet > 6 && $planet < 9 && $ret['walls'] == -1)
        {
            $ret['power'] = -5;
            $ret['migration'] = 1;
            $ret['migration_cn'] = '游走';
        }

        return $ret;
    }

    /**
     * 获取骰子 卜卦模式 信息
     * @return array
     */
    public function getDivinationInfo(array $detail, int $tid)
    {

        $settingData = (new AstroSettingUser1751())->getUserSettingByTid(['uid' => $detail['uid'], 'tid' => $tid, 'chart' => 'divination']);

        $Astrolog = Astrolog::getInstance();

        if (!empty($settingData))
        {
            $userSetting = ['divination' => $settingData];
        } else
        {
            $userSetting = config('astroset.setting1');
        }

        // 界主星参数数字转为字符串
        if (isset($userSetting['divination']['bound_type']))
        {
            if ($userSetting['divination']['bound_type'] === 0)
            {
                $userSetting['divination']['bound_type'] = 'default';
            } else
            {
                $userSetting['divination']['bound_type'] = 'ptolemy_world';
            }
        }

        $advanceInfo = [
            'year' => date('Y', $detail['create_time']) * 1,
            'month' => date('m', $detail['create_time']) * 1,
            'day' => date('d', $detail['create_time']) * 1,
            'hour' => date('H', $detail['create_time']) * 1,
            'minute' => date('i', $detail['create_time']) * 1,
            'timezone' => $detail['timezone'] * 1,
            'is_summer' => 0,
            'longitude' => $detail['longitude'],
            'latitude' => $detail['latitude'],
        ];
        $Astrolog->setAdvance($advanceInfo)
            ->setExecPrefix(config('astrolog.prefix'))
            ->setIsAstrolabe(true)
            ->setVersion(2);

        $details = $Astrolog->setUserSetting($userSetting)
            ->setGetDatas(['divination'])
            ->getAstroDatas()
            ->getDatas('divination');
        $details['question'] = $detail['question'];
        return $details;
    }
}